﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;

namespace WMI.NET
{
    /// <summary>
    /// 
    /// </summary>
    public static class Methods
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        /// <param name="Win32Name"></param>
        /// <param name="Value"></param>
        /// <returns></returns>
        public static SelectQuery ObjectQuery_WHERE(this ManagementBaseObject mbo, string Win32Name, string Value)
        {
            string query = mbo.GetPropertyValue(Value).ToString();
            query = query.Split('.')[1];
            SelectQuery selectQuery = new SelectQuery("SELECT * FROM " + Win32Name + " WHERE " + query);

            return selectQuery;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string FindSubClassName(this string path)
        {
            ManagementPath managementPath = new ManagementPath(path);

            ManagementScope managementScope = new ManagementScope(managementPath);

            SelectQuery query = new SelectQuery(managementScope.Path.ClassName, managementScope.Path.RelativePath.Split('.')[1]);

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, query);

            return searcher.SingleMBO().ClassPath.ClassName;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Win32ClassName"></param>
        /// <returns></returns>
        public static dynamic Win32ClassDynamicType(this string Win32ClassName)
        {
            dynamic[] Win32ClassConvert = WMI.NET.WMI_Conveter.getTypeByName(Win32ClassName);

            if (Win32ClassConvert.Count() != 1)
            {
                throw new Exception("Class Name (" + Win32ClassName + ") not found!");
            }
            else
            {
                return Win32ClassConvert[0];
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static dynamic GetSubWin32Class(this ManagementBaseObject mbo, string value)
        {
            string PropertyValue = mbo.GetPropertyValue(value).ToString();

            string Win32ClassName = PropertyValue.FindSubClassName();
            dynamic Win32ClassDynamic = Win32ClassName.Win32ClassDynamicType();


            return System.ComponentModel.TypeDescriptor.CreateInstance(
                    provider: null,
                    objectType: Win32ClassDynamic,
                    argTypes: new Type[] { typeof(ManagementBaseObject) },
                    args: new object[] { mbo.ObjectQuery_WHERE(Win32ClassName, value).Searcher().SingleMBO() });

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="SelectQuery"></param>
        /// <returns></returns>
        public static ManagementObjectSearcher Searcher(this SelectQuery SelectQuery)
        {
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(SelectQuery);
            return searcher;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="searcher"></param>
        /// <returns></returns>
        public static ManagementBaseObject SingleMBO(this ManagementObjectSearcher searcher)
        {
            var Enumerator = searcher.Get().GetEnumerator();
            Enumerator.MoveNext();
            return Enumerator.Current;
        }


    }
}
